From: Joseph Marrero Corchado Date: Wed, 15 Jul 2026 17:07:03 +0000 (-0400) Subject: static-delta: guard bspatch against integer truncation on 32-bit X-Git-Tag: archive/raspbian/2026.4-1+rpi1^2~9^2^2~20^2~1 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=88f35c5afb6f86c18e8f17d28259ac00336a5051;p=ostree.git static-delta: guard bspatch against integer truncation on 32-bit On 32-bit systems (sizeof(gsize)==4), the attacker-controlled content_size (a guint64) is silently truncated when passed to g_malloc0(), which takes gsize. Meanwhile bspatch() receives the full 64-bit value as int64_t newsize and writes according to it, producing a heap buffer overflow. Add an explicit check that content_size fits in both gsize and int64_t before the allocation. Use separate typed locals (alloc_size, newsize) to make the truncation-free intent clear and pass newsize to bspatch(). Addresses: RHEL-189207 CWE-680, CWE-122, CWE-190 --- diff --git a/src/libostree/ostree-repo-static-delta-processing.c b/src/libostree/ostree-repo-static-delta-processing.c index 94876fa4..c5445e7f 100644 --- a/src/libostree/ostree-repo-static-delta-processing.c +++ b/src/libostree/ostree-repo-static-delta-processing.c @@ -414,7 +414,27 @@ dispatch_bspatch (OstreeRepo *repo, StaticDeltaExecutionState *state, GCancellab if (!input_mfile) return FALSE; - g_autofree guchar *buf = g_malloc0 (state->content_size); + /* Guard against integer truncation on 32-bit systems: g_malloc0() takes + * gsize which is 32-bit on those platforms, but bspatch() uses the full + * int64_t newsize. Without this check a crafted content_size > G_MAXSIZE + * would allocate a truncated (small) buffer while bspatch() writes using + * the full 64-bit value, causing a heap buffer overflow. + * (CVE / RHEL-189207, CWE-680, CWE-122) + */ + if (G_UNLIKELY (state->content_size > G_MAXSIZE + || state->content_size > (guint64)G_MAXINT64)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, + "Invalid content size %" G_GUINT64_FORMAT + " in static delta bspatch operation", + state->content_size); + return FALSE; + } + + const gsize alloc_size = (gsize)state->content_size; + const int64_t newsize = (int64_t)state->content_size; + + g_autofree guchar *buf = g_malloc0 (alloc_size); struct bzpatch_opaque_s opaque; opaque.state = state; @@ -424,7 +444,7 @@ dispatch_bspatch (OstreeRepo *repo, StaticDeltaExecutionState *state, GCancellab stream.read = bspatch_read; stream.opaque = &opaque; if (bspatch ((const guint8 *)g_mapped_file_get_contents (input_mfile), - g_mapped_file_get_length (input_mfile), buf, state->content_size, &stream) + g_mapped_file_get_length (input_mfile), buf, newsize, &stream) < 0) return glnx_throw (error, "bsdiff patch failed");